//
// File: arburg.cpp
//
// MATLAB Coder version            : 5.4
// C/C++ source code generated on  : 21-Mar-2025 17:03:22
//

// Include Files
#include "arburg.h"
#include "rt_nonfinite.h"
#include "coder_array.h"
#include <cmath>

// Function Declarations
static void binary_expand_op(coder::array<double, 1U> &in1,
                             const coder::array<double, 1U> &in3, int in4,
                             int in5, double in6,
                             const coder::array<double, 1U> &in7, int in8,
                             int in9, int in10);

static void binary_expand_op(coder::array<double, 1U> &in1, int in3, double in4,
                             const coder::array<double, 1U> &in5, int in6,
                             int in7);

// Function Definitions
//
// Arguments    : coder::array<double, 1U> &in1
//                const coder::array<double, 1U> &in3
//                int in4
//                int in5
//                double in6
//                const coder::array<double, 1U> &in7
//                int in8
//                int in9
//                int in10
// Return Type  : void
//
static void binary_expand_op(coder::array<double, 1U> &in1,
                             const coder::array<double, 1U> &in3, int in4,
                             int in5, double in6,
                             const coder::array<double, 1U> &in7, int in8,
                             int in9, int in10)
{
  int stride_0_1;
  int stride_1_1;
  stride_0_1 = ((in5 - in4) + 1 != 1);
  stride_1_1 = ((in9 - in8) + 1 != 1);
  for (int i{0}; i < in10; i++) {
    in1[i] = in3[in4 + i * stride_0_1] + in6 * in7[in8 + i * stride_1_1];
  }
}

//
// Arguments    : coder::array<double, 1U> &in1
//                int in3
//                double in4
//                const coder::array<double, 1U> &in5
//                int in6
//                int in7
// Return Type  : void
//
static void binary_expand_op(coder::array<double, 1U> &in1, int in3, double in4,
                             const coder::array<double, 1U> &in5, int in6,
                             int in7)
{
  coder::array<double, 2U> b_in1;
  int stride_0_1;
  int stride_1_1;
  b_in1.set_size(1, in7);
  stride_0_1 = (in3 + 1 != 1);
  stride_1_1 = (in6 + 1 != 1);
  for (int i{0}; i < in7; i++) {
    b_in1[i] = in1[i * stride_0_1] + in4 * in5[i * stride_1_1];
  }
  stride_0_1 = b_in1.size(1);
  for (int i{0}; i < stride_0_1; i++) {
    in1[i] = b_in1[i];
  }
}

//
// Arguments    : const ::coder::array<double, 1U> &x
//                double p
//                ::coder::array<double, 2U> &Aout
//                double *Eout
// Return Type  : void
//
namespace coder {
void arburg(const ::coder::array<double, 1U> &x, double p,
            ::coder::array<double, 2U> &Aout, double *Eout)
{
  array<double, 2U> a;
  array<double, 2U> b_ebp;
  array<double, 1U> ebp;
  array<double, 1U> ef;
  array<double, 1U> efp;
  array<double, 1U> xm;
  double E;
  double k;
  int N;
  int i;
  int i1;
  int loop_ub;
  int loop_ub_tmp;
  if (x.size(0) == 1) {
    xm.set_size(1);
    xm[0] = x[0];
  } else {
    xm.set_size(x.size(0));
    loop_ub = x.size(0);
    for (i = 0; i < loop_ub; i++) {
      xm[i] = x[i];
    }
  }
  N = xm.size(0);
  loop_ub_tmp = static_cast<int>(p + 1.0);
  Aout.set_size(1, loop_ub_tmp);
  if (xm.size(0) < 2) {
    i = 0;
    i1 = 0;
  } else {
    i = 1;
    i1 = xm.size(0);
  }
  loop_ub = i1 - i;
  efp.set_size(loop_ub);
  for (i1 = 0; i1 < loop_ub; i1++) {
    efp[i1] = xm[i + i1];
  }
  if (xm.size(0) - 1 < 1) {
    loop_ub = 0;
  } else {
    loop_ub = xm.size(0) - 1;
  }
  ebp.set_size(loop_ub);
  for (i = 0; i < loop_ub; i++) {
    ebp[i] = xm[i];
  }
  ef.set_size(xm.size(0) - 1);
  loop_ub = xm.size(0);
  for (i = 0; i <= loop_ub - 2; i++) {
    ef[i] = 0.0;
  }
  loop_ub = xm.size(0);
  k = 0.0;
  for (i = 0; i < loop_ub; i++) {
    k += xm[i] * xm[i];
  }
  E = k / static_cast<double>(xm.size(0));
  a.set_size(1, loop_ub_tmp);
  for (i = 0; i < loop_ub_tmp; i++) {
    a[i] = 0.0;
  }
  a[0] = 1.0;
  i = static_cast<int>(p);
  for (int m{0}; m < i; m++) {
    double d;
    double d1;
    double y;
    int i2;
    int i3;
    d = static_cast<double>(N) - (static_cast<double>(m) + 1.0);
    if (static_cast<int>(d) < 1) {
      loop_ub = 0;
      i1 = 0;
      i2 = 0;
    } else {
      loop_ub = static_cast<int>(d);
      i1 = static_cast<int>(d);
      i2 = static_cast<int>(d);
    }
    k = 0.0;
    if (i1 >= 1) {
      for (loop_ub_tmp = 0; loop_ub_tmp < i1; loop_ub_tmp++) {
        k += efp[loop_ub_tmp] * efp[loop_ub_tmp];
      }
    }
    y = 0.0;
    if (i2 >= 1) {
      for (loop_ub_tmp = 0; loop_ub_tmp < i2; loop_ub_tmp++) {
        y += ebp[loop_ub_tmp] * ebp[loop_ub_tmp];
      }
    }
    d1 = 0.0;
    for (i1 = 0; i1 < loop_ub; i1++) {
      d1 += -2.0 * ebp[i1] * efp[i1];
    }
    k = d1 / (k + y);
    if (static_cast<int>(d) < 2) {
      i1 = 0;
      i2 = 0;
      loop_ub_tmp = 0;
      i3 = 0;
    } else {
      i1 = 1;
      i2 = static_cast<int>(d);
      loop_ub_tmp = 1;
      i3 = static_cast<int>(d);
    }
    if (d - 1.0 < 1.0) {
      loop_ub = 0;
    } else {
      loop_ub = static_cast<int>(d - 1.0);
    }
    if (i2 - i1 == i3 - loop_ub_tmp) {
      for (i2 = 0; i2 < loop_ub; i2++) {
        ef[i2] = efp[i1 + i2] + k * ebp[loop_ub_tmp + i2];
      }
    } else {
      binary_expand_op(ef, efp, i1, i2 - 1, k, ebp, loop_ub_tmp, i3 - 1,
                       loop_ub);
    }
    if (d - 1.0 < 1.0) {
      i1 = 0;
      i2 = 0;
      loop_ub = 0;
    } else {
      i1 = static_cast<int>(d - 1.0);
      i2 = static_cast<int>(d - 1.0);
      loop_ub = static_cast<int>(d - 1.0);
    }
    if (i1 == i2) {
      b_ebp.set_size(1, loop_ub);
      for (i1 = 0; i1 < loop_ub; i1++) {
        b_ebp[i1] = ebp[i1] + k * efp[i1];
      }
      loop_ub = b_ebp.size(1);
      for (i1 = 0; i1 < loop_ub; i1++) {
        ebp[i1] = b_ebp[i1];
      }
    } else {
      binary_expand_op(ebp, i1 - 1, k, efp, i2 - 1, loop_ub);
    }
    if (d - 1.0 < 1.0) {
      loop_ub = 0;
    } else {
      loop_ub = static_cast<int>(d - 1.0);
    }
    for (i1 = 0; i1 < loop_ub; i1++) {
      efp[i1] = ef[i1];
    }
    b_ebp.set_size(1, m + 1);
    for (i1 = 0; i1 <= m; i1++) {
      b_ebp[i1] = a[i1 + 1] + k * a[m - i1];
    }
    loop_ub = b_ebp.size(1);
    for (i1 = 0; i1 < loop_ub; i1++) {
      a[i1 + 1] = b_ebp[i1];
    }
    k = std::abs(k);
    E *= 1.0 - k * k;
  }
  loop_ub = a.size(1);
  for (i = 0; i < loop_ub; i++) {
    Aout[i] = a[i];
  }
  *Eout = E;
}

} // namespace coder

//
// File trailer for arburg.cpp
//
// [EOF]
//
